import { currentUser } from './misc'

// eslint-disable-next-line @typescript-eslint/naming-convention
async function GM_fetch(args: any): Promise<string> {
    return await new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
            ...args,
            onload: data => { resolve(data.response) },
            onerror: err => { reject(err) }
        })
    })
}

const BASE_URL = 'note.yurzhang.com'
const THRESHOLD = 0
let updateValue = parseInt(localStorage.getItem('sbb_updateValue') ?? '100')

async function addUpdateValue(value: number): Promise<void> {
    updateValue += value
    if (updateValue >= THRESHOLD) await fetchHaru()
    localStorage.setItem('sbb_updateValue', updateValue.toString())
}

async function fetchHaru(): Promise<void> {
    let data = await GM_fetch({
        method: 'GET',
        url: `https://${BASE_URL}/notes`
    })
    localStorage.setItem('sbb_haru_cache', data)
    data = await GM_fetch({
        method: 'GET',
        url: `https://${BASE_URL}/logs`
    })
    localStorage.setItem('sbb_log_cache', data)
    updateValue = 0
}
async function getHarus(): Promise<Haru[]> {
    await addUpdateValue(7)
    return JSON.parse(localStorage.getItem('sbb_haru_cache') ?? '[]')
}

async function getHarusByTags(tags: string[]): Promise<Haru[]> {
    const harus = await getHarus()
    return harus.filter(v => tags.map(tag => v.tags.includes(tag)).reduce((a, b) => a && b, true))
}

async function createHaru(content: string, tags: string[]): Promise<number> {
    const createResponse = await GM_fetch({
        method: 'POST',
        url: `https://${BASE_URL}/notes`,
        data: JSON.stringify({ author: currentUser, content }),
        headers: { 'Content-Type': 'application/json' }
    })
    console.log(createResponse)
    const id: number = JSON.parse(createResponse).id
    await GM_fetch({
        method: 'POST',
        url: `https://${BASE_URL}/notes/${id}/tags`,
        data: JSON.stringify({ author: currentUser, tags }),
        headers: { 'Content-Type': 'application/json' }
    })
    await addUpdateValue(100)
    return id
}

async function updateHaru(id: number, content: string): Promise<void> {
    await GM_fetch({
        method: 'PUT',
        url: `https://${BASE_URL}/notes/${id}`,
        data: JSON.stringify({ author: currentUser, content }),
        headers: { 'Content-Type': 'application/json' }
    })
}

async function getLogs(): Promise<Log[]> {
    await addUpdateValue(9)
    return JSON.parse(localStorage.getItem('sbb_log_cache') ?? '[]')
}

export { getHarusByTags, createHaru, getLogs, updateHaru }
